#ifndef _BK9000_UNIT_EVENT_H_
#define _BK9000_UNIT_EVENT_H_

#include <stdint.h>

#include "bk9000_device_type.h"

#if __STDC_VERSION__ < 199901L
    #error "must be C99 or higher. try to add '-std=c99' to compile parameters"
#endif

#ifndef __packed
    #define __packed __attribute__((packed, aligned(1)))
#endif

#ifdef __cplusplus
extern "C"
{
#endif

    typedef union __packed
    {
        struct
        {
            uint8_t alarm       : 1; /**< alarm event */
            uint8_t pre_alarm   : 1; /**< warning */
            uint8_t power_fault : 1; /**< external power fault */

            uint8_t in_oc       : 1; /**< input open circuit  */
            uint8_t in_sc       : 1; /**< input shorts circuit  */
            uint8_t out_oc      : 1; /**< output open circuit  */
            uint8_t out_sc      : 1; /**< output shorts circuit  */
            uint8_t             : 1; /**< reserve, set 1 claer alarm */
        };

        struct
        {
            uint8_t             : 3;
            uint8_t temp_fault  : 1; /**< thermistor sensor fault */
            uint8_t smoke_fault : 1; /**< smoke sensor fault  */
            uint8_t gas_fault   : 1; /**< gas sensor fault  */
            uint8_t             : 2;
        };

        struct
        {
            uint8_t alarm : 2;
            uint8_t fault : 5;
            uint8_t       : 1;
        } mask;
        uint8_t value;
    } bk9000_unit_event_legacy_t;

    typedef union __packed
    {
        struct
        {
            uint8_t alarm          : 1; /**< alarm */
            uint8_t pre_alarm      : 1; /**< warning */
            uint8_t power_fault    : 1; /**< power fault */

            uint8_t in_oc          : 1; /**< input open circuit fault */
            uint8_t in_sc          : 1; /**< input short circuit fault */
            uint8_t out_oc         : 1; /**< output open circuit fault */
            uint8_t out_sc         : 1; /**< output short circuit fault */
            uint8_t                : 1;

            uint8_t isolation      : 2;
            uint8_t                : 2;
            uint8_t type_error     : 1; /**< Type Error */
            uint8_t repeat_address : 1; /**< Repeat Address */
            uint8_t tx_error       : 1; /**< Tx Error  */
            uint8_t no_reply       : 1; /**< Non Reply And event reset, unit set 1 claer alarm */
        };

        struct
        {
            bk9000_unit_event_legacy_t legacy; /**< lsb state compatible bk8000 state */
            uint32_t : 24;
        };

        uint8_t  u8val;
        uint16_t u16val;
        uint32_t u32val;
        uint32_t value;
    } bk9000_unit_event_t;

    typedef union __packed
    {
        struct
        {
            uint16_t num_bcd;
            uint8_t  day_bcd;
            uint8_t  month_bcd;
            uint8_t  year_bcd;
            uint8_t  type;
        };
        uint8_t id[6];
    } bk9000_sn_t;

    struct bk9000_unit_info
    {
        const uint8_t sn[6];   /**< 设备长地址 */
        uint8_t       type;    /**< 单元类型 */
        uint8_t       address; /**< 单元短地址 */
        uint8_t       trunk;   /**< 单元主干号 */
        uint8_t       branch;  /**< 单元分支号 */
        struct
        {
            uint16_t type : 4;  /**< 区类型 */
            uint16_t id   : 12; /**< 区号 */
        } ZM[8];                /**< 单元区控制, 保留 */

        uint8_t data[16]; /**< 单元数据, MAX 16byte */
    };

    typedef struct bk9000_unit_info bk9000_unit_info_t;

    struct __packed bk9000_unit_operation
    {
        uint16_t alarm_cnt;        /* 报警统计 */
        uint16_t fault_cnt;        /* 总故障次数 */
        uint16_t power_on_cnt;     /* 上电次数 */
        uint16_t program_cnt;      /* 编址记录 */
        uint32_t working_hours;    /* 总工作小时数 */
        uint32_t maintenance_time; /* 上一次维保时间 */
    };

    typedef struct bk9000_unit_operation bk9000_unit_operation_t;

    /**
     * @brief 单元阈值
     *
     */
    typedef struct __packed
    {
        int16_t alarm;     /**< 报警值 */
        int16_t pre_alarm; /**< 预警值 */
    } bk9000_unit_thd_data_t;

    /**
     * @brief 探测器默认阈值下发
     *
     */
    typedef struct __packed
    {
        uint8_t calc_mode; /**< 计算模式, 与或非 */
        struct
        {
            bk9000_unit_thd_data_t smoke; /**< 烟雾阈值 */
            bk9000_unit_thd_data_t temp;  /**< 温度阈值 */
            bk9000_unit_thd_data_t gas;   /**< 气体阈值 */
        } thd;
    } bk9000_unit_detector_thd_t;

    enum
    {
        BK9000_EVENT_ID_RST = 1,
        BK9000_EVENT_ID_PRO,
        BK9000_EVENT_ID_EVENT,
        BK9000_EVENT_ID_ALARM,
    };

    /* 单元事件记录基础数据, 可自行扩展, MAX: 64Byte, User Data: 48Byte */
    struct bk9000_event_record
    {
        uint32_t event_id;  /* 事件码, see BK9000_EVENT_ID_xxx */
        uint32_t timestamp; /* 事件记录时间戳 */
        uint8_t  r[8];      /* 保留 */
    };

    typedef struct bk9000_event_record bk9000_event_record_t;

#ifdef __cplusplus
}
#endif

#endif /* _BK9000_UNIT_EVENT_H_ */
